推播服務是App的一種與使用者互動的特色服務,使用者可以透過推播隨時隨地與App進行互動。App推播功能有許多的種類,有本地推播、遠程推播、 App內推播等等......,接收推播的處理方式有單純的開啟App、跳轉到指定頁面、接收使者輸入並處理等各式各樣的應用。本文聚焦在遠程推播的實作以及點擊推播訊息後,在指定的頁面程式中取得推播內容,以利工程師對推播內容做後續的處理。
本文需求的場景是:業主有一套以多人填製表單為主要功能的網站系統,網站有發送訊息到Firebase的能力,在前一人完成表單添置後,需傳送到下一個使用者做處理。
網站系統送出表單後,系統同步發送推播訊息到下一個使用者的App,此推播訊息內容有該表單的網址,當被通知者接收到推播訊息,點擊推播後,能夠直接開啟App,依推播訊息內容中的網址跳轉至該表單。手機的App是web base的形式,為了完成這項功能,我們把需要在App上循序執行下列步驟:
建立接收Firebase推播的接口
Firebase提供iOS相對應的函式庫,讓iOS程式設計師使用他們提供的雲端功能,設計師只要在App中引入就可以了,網址是:https://github.com/firebase/firebase-ios-sdk
當sdk安裝完成後,回到專案的AppDelegate.swift檔案中,引入FirebaseCore以及FirebaseMessaging 這兩個函式庫,並且在 didFinishLaunchingWithOptions (App啟動初始化)初始化的程式碼為:
FirebaseApp.configure()
UNUserNotificationCenter.current().delegate = self
Messaging.massaging().delegate = self
然後,在使用者第一次登入App時,要請求接收推播權限,程式碼如下:
設定接收推播訊息的方式,此處是可接收彈跳視窗、文字內容及聲音
let authOptons: UNAuthorizationOptions = [.alert, .badge, .sound]
利用UNUserNotificitionCenter方法請求允許開啟通知通道
UNUserNotificitionCenter.current().requestAuthorization(options: authOptions, completionHandler:{_, _, in})
將App註冊可接收推播訊息
Application.registerForRemoteNotifications()
開啟App的Push Notification及背景服務功能
接下來要開啟App的推播功能,這個動作要在App層級做設定,首先在左邊的專案管理頁面點擊專案根目錄,此時右邊匯出先專案的設定畫面,選擇Sign&Capabilities頁籤,按下左上角的Capability,會彈出此專案的功能擴展選擇器,鍵入 Push 可找到 Push Notifications圖案,點擊後,XCode就會把此擴充功能加入到此專案中。
同樣的方式,我們在功能擴展選擇器中,鍵入 Back 可找到 Background Modes圖案,也把他加入專案後,將 Background fetch、Remote Notifications、Background processing打勾。表示App有某些工作必須在背景執行。
最後一步是處理App與Firebase之間驗證機制,將頁籤切換到Info,下方有個URL Type(0)的選項,將它展開後會看到 URL Schemes,在此處要輸入Firebase專案的驗證代號,開啟GoogleService-Info檔案,找到第3行 REVERSED_CLIENT_ID,將其value複製貼上到 URL Schemes 的文字匡內,這樣App的設定就完成了
擴展AppDelegate的方法
在iOS上執行Firebase推播,須在AppDelegate類別中繼承UNUserNotificationCenterDelegate並實作3個方法以及MessagingDelegate中實作2個方法。
首先我們看到UNUserNotificationCenterDelegate要實作的方法,推播訊息送達App時,會有3種情況:
第一種是App尚未開啟(關閉)
第二種是App開啟正在使用時(前景)
第三種是App並未關閉在背景運行的時候(背景)
這三種情況收到推播訊息後,要如何對訊息做處理,就在這個類別中設計一些方法來告訴App。
首先我們處理App未開啟的情況:
App未開啟的情況,建立application方法,並以 didReceiveRemteNotification來處理 userInfo物件,並指定本方法為非同步處理,方法要回傳UIBackgroundResult物件(如圖6)。userInfo是APN發送過來App的訊息物件,結構如下:
userInfo : [
AnyHashable("google.c.a.ts"): 1671757895, AnyHashable("google.c.a.c_id"): 4556509826510363819, AnyHashable("gcm.n.e"): 1,
AnyHashable("google.c.a.e"): 1, AnyHashable("gcm.message_id"): 1671757895087640,
AnyHashable("google.c.a.c_l"): 測試, AnyHashable("google.c.sender.id"): 568638775392,
AnyHashable("aps"): {
alert = {
body = "這是測試訊息";
title = "20221223測試訊息";
};
"mutable-content" = 1;
},
AnyHashable("google.c.a.udt"): 0, AnyHashable("google.c.fid"): ftDzBG4L6UGKhlh9GZRouz
]
在這個結構中,常用的資訊有:通知編號(gcm.message_id)、通知名稱(google.c.a.c_l)、訊息本體(aps)、訊息通知視窗(alert),其中通知視窗內的訊息包含訊息內容(body)、訊息標題(title),因為本案例需要訊息中的body內包含的網址資訊,我們要透過三層來擷取。(如圖6)
擷取到body字串後,要把個字串從Delegate傳到指定的viewController中,可利用
NotificationCenter.default.post(name: Notification.Name("viewController對應的參數名稱"), object: 要傳過去的字串, userInfo: 訊息結構名稱)
完成訊息內文傳遞到相對應的viewController的變數。
App在背景的情況,建立application方法,並以 didReceive來處理 userInfo物件,並指定本方法為非同步處理。因本方法中已經有宣告UNNotificationResponse物件(respons變數)來接收userInfo,因此,可以使用response.
notification.request.content.userInfo取得userInfo物件,或是response.notification.request.content.title
取得title字串,response.notification.request.content.body取得body字串(如圖7)。
擷取到body字串後,要把個字串從Delegate傳到指定的viewController中。
與未開啟的情況相同,可利用
NotificationCenter.default.post(name: Notification.Name("viewController對應的參數名稱"), object: 要傳過去的字串, userInfo: 訊息結構名稱)
完成訊息內文傳遞到相對應的viewController的變數。
App在開啟的情況,建立application方法,並以 willPresent來處理 userInfo物件,並指定本方法為非同步處理。因本方法中已經有宣告UNNotification物件(notification變數)來接收userInfo,因此,可以使用notification.
notification.request.content.userInfo取得userInfo物件,或是notification.request.content.title
取得title字串,notification.request.content.body取得body字串(如圖7)。
擷取到body字串後,要把個字串從Delegate傳到指定的viewController中。
與未開啟的情況相同,可利用
NotificationCenter.default.post(name: Notification.Name("viewController對應的參數名稱"), object: 要傳過去的字串, userInfo: 訊息結構名稱)
完成訊息內文傳遞到相對應的viewController的變數。
在viewController中接收通播訊息內容
推播通知是即時產生的內容,這些內容並不是長期存在變數中的,因此,接收推播內容的變數不會在主要執行序中操作,也不是在App的生命週期中,所以必須在App的生命週期外部建立一個監聽機制,並將接收推播訊息後要執行的工作另外寫在該函式中。(如圖9)
宣告@objc func notificationArrived(notification: Notification)方法,用以處理推播訊息抵達的操作,本案例的需求是:推播內容是一串網址,當取得推播內容後,將webview物件能跳轉到該網址的頁面。所以把跳轉頁面的操作寫成function並在接收到訊息後呼叫它。
在指定的viewController中宣告一個全域變數用來接收推播訊息的字串,這個全域變數的型別要跟前一節在AppDelegate中的三個方法中 “NotificationCenter.default.post(name:
Notification.Name("viewController對應的參數名稱"), object: 要傳過去的字串, userInfo: 訊息結構名稱)”的描述的object引數相同(如圖10),如此一來,viewController就能在@objc func notificationArrived(notification: Notification)的notification.object取得推播的內容。
以上就是本次iOS推播與web view跳轉的實作筆記,希望對大家有幫助。